home *** CD-ROM | disk | FTP | other *** search
- /* openCloseFiles ([params]) XFCN source code
- * copyright 1990 - Mark Zimmermann
- *
- * - specially modified (for potential CD-ROM applications) -- so that it can:
- * 1) open any file types, not just TEXT and CTLZ, for database & indices
- * 2) ask for location of the index file(s) if not found in same folder
- * as the main file, with the suffix '.k' or '.p'
- *
- * Call this XFCN as 'openCloseFiles([optional list of numbers here])'.
- *
- * If the XFCN is called with no arguments, it puts up the standard files
- * dialog box and gives back in return the file refNums for the main
- * (document/database) file, *.k, and *.p files, on one line, in
- * that order, separated by spaces. The XFCN also returns, on a second
- * line, the file name of the file that has been opened.
- *
- * If the XFCN is passed any numerical parameters, it attempts to
- * close them (assuming they are file refNums) and doesn't try to
- * open anything....
- *
- * If an error while opening a file seems to occur, the XFCN attempts
- * to close all files that have already been opened, and returns with
- * an error msg instead of the three file refNums. No error checking
- * is done on closing files, since there's not much that one could
- * do about such an error in any case....
- *
- */
-
-
- #include <MacTypes.h>
- #include <FileMgr.h>
- #include <StdFilePkg.h>
- #include <HyperXCmd.h>
- #include <SetUpA4.h>
-
- #define NULL 0
-
-
- pascal void main (XCmdBlockPtr paramPtr);
- int zGetFile (Str255 *fileNamePtr, int *volRefNumPtr, long fileType);
- void give_msg (char *msg);
- void returnErrorMsg (XCmdBlockPtr paramPtr, char *msg);
- long atol (char *s);
- void ltoaR (char *ansp, long n, int maxDigits);
- int strlen (char *s);
- char *strcpy (char *s1, char *s2);
-
-
- pascal void main (paramPtr)
- XCmdBlockPtr paramPtr;
- {
- Str255 fileName;
- int refNum, volRefNum, textFileRefNum, keyFileRefNum, ptrFileRefNum,
- i, errNum;
- Handle answer;
- WindowRecord w_record;
- WindowPtr info_window;
- Rect b_rect;
-
- RememberA0 ();
- SetUpA4();
- if (paramPtr->paramCount != 0)
- {
- for (i = 0; i < paramPtr->paramCount; ++i)
- {
- refNum = atol (*(paramPtr->params[i]));
- FSClose (refNum);
- }
- RestoreA4();
- return;
- }
-
- /* set up a window to give user feedback during file opening... */
- b_rect.top = 30;
- b_rect.left = 12;
- b_rect.bottom = 332;
- b_rect.right = 500;
- info_window = NewWindow (&w_record, &b_rect, "\p", (Boolean)1,
- dBoxProc, (WindowPtr)-1, (Boolean)0, (long)0);
- ShowWindow (info_window);
- SetPort (info_window);
- TextFont (0);
- give_msg ("\pPlease choose a database (indexed file) to open...");
-
- /* note that file type 'TEXT' is now ignored here! */
- if (! zGetFile (&fileName, &volRefNum, 'TEXT'))
- {
- DisposeWindow (info_window);
- RestoreA4();
- return;
- }
-
- errNum = FSOpen (&fileName, volRefNum, &textFileRefNum);
- if (errNum != noErr && errNum != opWrErr)
- {
- returnErrorMsg (paramPtr,
- "{Sorry, error in opening database file!}");
- DisposeWindow (info_window);
- RestoreA4();
- return;
- }
-
- *(fileName + *fileName + 1) = '.';
- *(fileName + *fileName + 2) = 'k';
- *fileName += 2;
- errNum = FSOpen (&fileName, volRefNum, &keyFileRefNum);
- if (errNum != noErr && errNum != opWrErr)
- {
- SysBeep (10);
- give_msg ("\p");
- give_msg ("\pSorry, can't find the index key ('.k') file for this database!");
- give_msg ("\pPlease locate it, or cancel...");
-
- /* note that file type 'CTLZ' is now ignored here! */
- if (! zGetFile (&fileName, &volRefNum, 'CTLZ'))
- {
- FSClose (textFileRefNum);
- DisposeWindow (info_window);
- RestoreA4();
- return;
- }
- else
- {
- errNum = FSOpen (&fileName, volRefNum, &keyFileRefNum);
- if (errNum != noErr && errNum != opWrErr)
- {
- FSClose (textFileRefNum);
- returnErrorMsg (paramPtr,
- "{Sorry, error in opening index key ('.k') file!}");
- DisposeWindow (info_window);
- RestoreA4();
- return;
- }
- }
- }
-
- *(fileName + *fileName) = 'p';
- errNum = FSOpen (&fileName, volRefNum, &ptrFileRefNum);
- if (errNum != noErr && errNum != opWrErr)
- {
- SysBeep (10);
- give_msg ("\p");
- give_msg ("\pSorry, can't find the index ptr ('.p') file for this database!");
- give_msg ("\pPlease locate it, or cancel...");
-
- /* note that file type 'CTLZ' is now ignored here! */
- if (! zGetFile (&fileName, &volRefNum, 'CTLZ'))
- {
- FSClose (textFileRefNum);
- FSClose (keyFileRefNum);
- DisposeWindow (info_window);
- RestoreA4();
- return;
- }
- else
- {
- errNum = FSOpen (&fileName, volRefNum, &ptrFileRefNum);
- if (errNum != noErr && errNum != opWrErr)
- {
- FSClose (textFileRefNum);
- FSClose (keyFileRefNum);
- returnErrorMsg (paramPtr,
- "{Sorry, error in opening index ptr ('.p') file!}");
- DisposeWindow (info_window);
- RestoreA4();
- return;
- }
- }
- }
-
- if ((answer = NewHandle (64)) == NULL)
- {
- FSClose (textFileRefNum);
- FSClose (keyFileRefNum);
- FSClose (ptrFileRefNum);
- returnErrorMsg (paramPtr,
- "{Sorry, bad out of memory error in XFCN openFiles call!}");
- DisposeWindow (info_window);
- RestoreA4();
- return;
- }
-
- ltoaR (*answer, textFileRefNum, 6);
- ltoaR (*answer + 6, keyFileRefNum, 6);
- ltoaR (*answer + 12, ptrFileRefNum, 6);
- *(*answer + 18) = '\r';
- for (i = 1; i <= *fileName - 2; ++i)
- *(*answer + 18 + i) = fileName[i];
- *(*answer + 18 + i) = '\0';
-
- paramPtr->returnValue = answer;
- DisposeWindow (info_window);
- RestoreA4();
- return;
- }
-
-
- /* this routine does the standard files dialog to get the name of the main file
- * of the database; other file names are gotten from that by putting
- * a '.k' or a '.p' at the end. This routine returns 1 if all is well,
- * or 0 if the user cancels out...
- *
- * special mod to open any file, not just type text...keep the myFileTypes
- * parameter in there, even though it's not used any more....who knows when
- * it might come in handy?!
- */
-
- int zGetFile (fileNamePtr, volRefNumPtr, fileType)
- Str255 *fileNamePtr;
- int *volRefNumPtr;
- long fileType;
- {
- SFTypeList myFileTypes;
- Point SFGwhere;
- SFReply myReply;
- register int i;
-
- SFGwhere.v = 90;
- SFGwhere.h = 82;
- myFileTypes[0] = fileType;
-
- /* main change is to put in the '-1' here to signify that file
- * type doesn't matter to SFGetFile
- */
- SFGetFile (SFGwhere, "\p", 0L, -1, myFileTypes, 0L, &myReply);
-
- if (myReply.good)
- {
- for (i = *myReply.fName; i >= 0; --i)
- (*fileNamePtr)[i] = myReply.fName[i];
- *volRefNumPtr = myReply.vRefNum;
- return (1);
- }
- else
- return (0);
- }
-
-
- /* tiny routine to put a message into my message window.... takes in a
- * PASCAL type string and displays it nicely....
- */
-
- void give_msg (msg)
- char *msg;
- {
- Rect b_rect;
- RgnHandle theRgn;
-
- b_rect.top = b_rect.left = 0;
- b_rect.bottom = 302;
- b_rect.right = 488;
-
- theRgn = NewRgn ();
- ScrollRect (&b_rect, 0, -15, theRgn);
- DisposeRgn (theRgn);
-
- MoveTo (4, 295);
- DrawString (msg);
-
- return;
- }
-
-
- /* function to set the return value of the XFCN to a chosen error msg;
- * if there isn't enough free memory to give us a Handle to the msg,
- * beep a bit and then return!
- */
-
- void returnErrorMsg (paramPtr, msg)
- XCmdBlockPtr paramPtr;
- char *msg;
- {
- Handle answer;
- int msgLength;
-
- SysBeep (10);
- msgLength = strlen (msg);
- if ((answer = NewHandle (1 + msgLength)) == NULL)
- {
- SysBeep (10);
- SysBeep (10);
- return;
- }
-
- strcpy (*answer, msg);
- paramPtr->returnValue = answer;
- return;
- }
-
-
- /* function to convert alphanumeric string to a long int, from K&R...
- */
-
- long atol (s)
- register char *s;
- {
- int signflag = 0;
- register long r = 0;
-
- while (*s == ' ')
- s++;
-
- if (*s == '-')
- {
- signflag = 1;
- s++;
- }
- else if (*s == '+')
- s++;
-
- while (*s >= '0' && *s <= '9')
- r = r * 10 + (*s++ - '0');
-
- return (signflag ? -r : r);
- }
-
-
- /* function to convert a number into a string of width maxDigits and
- * store it right-justified, blank-filled on left; based on K&R p. 60
- * example of itoa().
- *
- * Error handling: put a '>' or '<' in leading place to warn of an
- * overflow (no room for digits on a positive or negative number,
- * respectively), and put a '^' in leading place to warn if no room
- * for '-' sign on negative number...
- */
-
- void ltoaR (ansp, n, maxDigits)
- register char *ansp;
- register long n;
- int maxDigits;
- {
- register int i;
- long sign;
-
- i = maxDigits - 1;
- if ((sign = n) < 0)
- n = -n;
-
- do
- {
- ansp[i--] = n % 10 + '0';
- }
- while ((n /= 10) > 0 && i >= 0);
-
- if (i < 0 && n > 0) /* ran out of room with digits still to go */
- {
- if (sign > 0)
- ansp[0] = '>'; /* positive overflow signal */
- else
- ansp[0] = '<'; /* negative overflow signal */
- }
- else
- {
- if (sign < 0)
- if (i >= 0)
- ansp[i--] = '-';
- else
- ansp[0] = '^'; /* no room for '-' sign signal */
- for ( ; i >= 0; --i)
- ansp[i] = ' ';
- }
-
- return;
- }
-
-
- /* function to determine the length of a string ... standard thing,
- * adapted from K&R p.98 ....
- */
-
- int strlen (s)
- register char *s;
- {
- char *s0 = s;
-
- while (*s++)
- ;
- return (s - s0 - 1);
- }
-
-
- /* function to copy a string from one place to another, in a rather
- * obvious fashion ... adapted from K&R p.101 ....
- */
-
- char *strcpy (s1, s2)
- register char *s1, *s2;
- {
- char *s = s1;
-
- while (*s1++ = *s2++)
- ;
- return (s);
- }
-
-